package org.googlecode.viewt.core.tools.contants;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.GnuParser;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.googlecode.viewt.core.tools.contants.types.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ConstantGenerateCommand {
	private static Logger logger = LoggerFactory
			.getLogger(ConstantGenerateCommand.class);
	public static final String OPT_CFG_FILE = "i";
	public static final String OPT_IMP_DEST = "imp";
	public static final String OPT_CFG_DEST = "cfg";
	public static final String OPT_RES_DEST = "res";
	public static final String OPT_PREFIX_PACKAGE = "prepack";
	public static final String OPT_COPYRIGHT = "copyright";
	public static final String OPT_AUTHOR = "author";
	private String constantCfgFile = null;

	private String impDestPath = null;

	private String cfgDestPath = null;

	private String resDestPath = null;

	private String prePackName = "com.leadron";

	private String copyright = null;

	private String author = null;

	private Constants constantsDef = null;

	public void parseArgs(String[] args) throws ParseException {
		
		
		CommandLineParser parser = new GnuParser();
		Options opt = new Options();

		// options.addOption(OptionBuilder.create("i"));
		opt.addOption(OptionBuilder.hasArg().isRequired().withDescription(
				"constant config file name by which to generate").create("i"));
		//		
		opt.addOption(OptionBuilder.hasArg().isRequired().withDescription(
				"path to output implementation class file").create("imp"));

		opt.addOption(OptionBuilder.hasArg().isRequired().withDescription(
				"path to output config file").create("cfg"));

		opt.addOption(OptionBuilder.hasArg().withDescription(
				"path to output resource file").create("res"));


		opt.addOption(OptionBuilder.hasArg().withDescription(
				"package prefix of generated class").create("prepack"));

		opt.addOption(OptionBuilder.hasArg().withDescription(
				"copyright information for generated code").create("copyright"));

		opt.addOption(OptionBuilder.hasArg().withDescription(
				"author information for generated code").create("author"));
		
		
	
		
		CommandLine cmdLine = parser.parse(opt, args);

		this.constantCfgFile = cmdLine.getOptionValue("i");
		this.impDestPath = cmdLine.getOptionValue("imp");
		this.cfgDestPath = cmdLine.getOptionValue("cfg");
		this.resDestPath = cmdLine.getOptionValue("res");
		if (cmdLine.hasOption("prepack"))
			this.prePackName = cmdLine.getOptionValue("prepack");
		if (cmdLine.hasOption("copyright"))
			this.copyright = cmdLine.getOptionValue("copyright");
		if (cmdLine.hasOption("author")) {
			this.author = cmdLine.getOptionValue("author");
		}

		System.out.println("Constant config file:\t\t" + this.constantCfgFile);
		System.out.println("Implement output path:\t" + this.impDestPath);
		System.out.println("Config output path:\t" + this.cfgDestPath);
		System.out.println("Resource output path:\t" + this.resDestPath);
		System.out.println("Package prefix:\t" + this.prePackName);
	}

	public void loadConfig() {
		logger.debug("Begin to load constant configuration...");
		this.constantsDef = ConstantUtil.loadConfig(this.constantCfgFile,
				this.prePackName);
		
		logger.debug("Load constant configuration succeed");
	}

	public boolean validateConfig() throws Exception {
		logger.debug("Begin to validate configuration...");

		boolean valide = ConstantUtil.validateConfig(this.constantsDef);
		if (!(valide))
			logger.error("Validate configuration fail");
		else {
			logger.debug("Validate configuration succeed");
		}
		return valide;
	}

	public void performGen() throws Exception {
		BaseConstantGenerator generator = null;

		logger.debug("Begin to generate constant implement file");
		generator = new ImpGenerator();
		generator.setCopyright(this.copyright);
		generator.setAuthor(this.author);
		generator.init(this.constantsDef, this.impDestPath);
		logger.debug("End generate constant implement file");
		generator.performGen();

		logger.debug("Begin to generate constant data config");
		generator = new DataConfigGenerator();
		generator.setCopyright(this.copyright);
		generator.setAuthor(this.author);
		generator.init(this.constantsDef, this.cfgDestPath);
		generator.performGen();
		logger.debug("End generate constant data config");

		logger.debug("Begin to generate resource file");
		ResourceGenerator resGenerator = new ResourceGenerator();
		resGenerator.setCopyright(this.copyright);
		resGenerator.setAuthor(this.author);
		resGenerator.setInitEnv(this.constantsDef, this.resDestPath);
		resGenerator.performGen();
		logger.debug("End generate resource file");
	}

	public static void main(String[] args) {
		System.out
				.println("Constant generator, Copyright (c) 2006-2008 Leadron Information Technoloy co.,Ltd.");
		try {
			ConstantGenerateCommand command = new ConstantGenerateCommand();
			command.parseArgs(args);
			command.loadConfig();
			if (!(command.validateConfig())) {
				System.out.println("Validate config fail");
				System.exit(-1);
			}
			command.performGen();
		} catch (ParseException parseEx) {
			System.out.println("Invalid command line argument, check the doc");
			System.out.println(parseEx.getMessage());
			System.exit(-1);
		} catch (Exception ex) {
			System.out.println("Generate constant source file fail");
			ex.printStackTrace();
			System.exit(-1);
		}

		System.out.println("Generation done.");
	}
}